﻿using System;
using System.Timers;

namespace ErgoBreak.Core
{
    internal class TimedAction : IBreakAction, IDisposable
    {
        #region Fields
        protected Timer timer;
        protected int duration;
        protected int remainedTime;
        protected readonly int MINUTE_TO_MILISECONDS = 60000;
        #endregion

        #region Events
        public EventHandler Finished;
        #endregion

        #region Constructors
        public TimedAction(int actionDuration)
        {
            this.timer = new Timer(1 * MINUTE_TO_MILISECONDS);
            this.timer.Elapsed += new ElapsedEventHandler(ObserveTime);
            this.remainedTime = actionDuration;
            this.duration = actionDuration;
        }
        #endregion

        #region Properties
        /// <summary>
        /// Gets the value indicating whether the action has time constraint.
        /// </summary>
        public bool IsTimed 
        {
            get { return true; }
        }

        /// <summary>
        /// Gets the value indicating whether the object has inherited from 
        /// 'IDisposable' interface. 
        /// </summary>
        public bool IsDisposable 
        {
            get { return true; }
        }

        /// <summary>
        /// Gets the original duration of the action.
        /// </summary>
        public int Duration
        {
            get { return this.duration; }
        }

        /// <summary>
        /// Gets the remained time from the break action.
        /// </summary>
        public int RemainedTime
        {
            get { return this.remainedTime; }
        }
        #endregion

        #region Public Methods
        /// <summary>
        /// Carries out the action it is suppose to do.
        /// </summary>
        public virtual void Perform()
        {
            // start the timer;
            this.timer.Start();
        }

        /// <summary>
        /// Releases the resources used by 'TimedAction' class.
        /// </summary>
        public void Dispose()
        {
            // clean up memory, and release the resources
            this.timer.Close();
            this.timer.Dispose();
        }
        #endregion

        #region Non-Public Methods
        private void ObserveTime(object sender, ElapsedEventArgs e)
        {
            if (this.remainedTime > 0)
            {
                remainedTime--;
            }
            else
            {
                this.timer.Stop();
                OnFinished();
            }
        }

        /// <summary>
        /// Raises the 'Finished' event.
        /// </summary>
        protected void OnFinished()
        {
            if (this.Finished != null)
                Finished(this, new EventArgs());
        }
        #endregion
    }
}
